<script setup lang="ts">
import { ref, watch } from 'vue'
import { ElMessage } from 'element-plus'
import { usePlanStore } from '@/stores/plan'
import type { ExerciseRecordI } from '@/types/record'
import { useUserStore } from '@/stores/user'
import dayjs from 'dayjs'
import type { ExerciseI } from '@/types/exercise'
import type { PickerConfirmEventParams, PickerOption } from 'vant'
import { getExerciseListByNameUtil } from '@/AGC/utils/exercise'
import { listByUserSelect } from '@/utils/format'
import {
  createExerciseRecordUtil,
  deleteExerciseRecordUtil,
  getExerciseRecordByDateUtil,
} from '@/AGC/utils/record'

const planStore = usePlanStore()
const formRef = ref()
const emptyModel: ExerciseRecordI = {
  id: 0,
  user_id: useUserStore().userInfo.id,
  date: dayjs().format('YYYY-MM-DD'),
  exercise_name: '',
  amount_unit: '',
  calories: 0,
}
const formModel = ref<ExerciseRecordI>({ ...emptyModel })
const rules = {
  exercise_name: [{ required: true, message: '请输入运动名称', trigger: 'blur' }],
  amount_unit: [{ required: true, message: '请输入运动量', trigger: 'blur' }],
}
// 弹窗类型
const showPopupType = ref('')
// 运动列表
const exerciseList = ref<ExerciseI[]>([])
// 临时运动列表
const tempExerciseList = ref<ExerciseI[]>([])
// 运动名称列表
const pickerNameList = ref<PickerOption[]>([])
// 搜索名字
const searchName = ref('')
// 搜索
const onSearch = async () => {
  if (!searchName.value) {
    ElMessage.warning('请先输入运动名称')
    return
  }
  // 1. 获取运动数据
  tempExerciseList.value = await getExerciseListByNameUtil(searchName.value)
  // 2. 提取运动名称
  pickerNameList.value = tempExerciseList.value.map((item) => {
    return { text: item.name, value: item.name }
  })

  if (tempExerciseList.value.length == 0) {
    ElMessage.warning('未找到相关运动')
  }
}
// 运动弹窗取消事件
const cancelOnExercisePopup = () => {
  showPopupType.value = ''
  searchName.value = ''
  tempExerciseList.value = []
  pickerNameList.value = []
}
// 运动弹窗确认事件
const confirmExerciseName = ({ selectedValues }: PickerConfirmEventParams) => {
  // 1. 将运动名称赋值给 formModel.exercise_name
  formModel.value.exercise_name = selectedValues[0].toString()
  // 2. 获取运动单位
  const exercise = tempExerciseList.value.find((item) => item.name == formModel.value.exercise_name)
  unit.value = exercise?.unit || ''
  // 3. 确定运动列表
  exerciseList.value = [...tempExerciseList.value]
  // 4. 整理记录数据
  integrateRecord()
  // 5. 关闭弹窗
  showPopupType.value = ''
}
// 运动单位
const unit = ref<string>('')
// 运动量弹窗打开之前的确认事件
const confirmExerciseAmountBefore = () => {
  if (!formModel.value.exercise_name) {
    ElMessage.warning('请先选择运动名称')
    return
  }

  showPopupType.value = 'exercise_amount'
}
// 运动量弹窗确认事件
const confirmExerciseAmount = ({ selectedValues }: PickerConfirmEventParams) => {
  formModel.value.amount_unit = selectedValues[0].toString()
  integrateRecord()
  showPopupType.value = ''
}
// 整理记录数据 => 运动名称和运动量都存在
const integrateRecord = () => {
  if (formModel.value.exercise_name && formModel.value.amount_unit) {
    const exercise = exerciseList.value.find((item) => item.name == formModel.value.exercise_name)

    if (exercise) {
      const amount = formModel.value.amount_unit.split(' ')[0]
      const multiple = Math.floor(Number(amount) / exercise.exercise_amount)
      formModel.value.calories = exercise.calories * multiple
    }
  }
}
// 添加运动
const addExercise = async (flag: number) => {
  await formRef.value.validate()

  if (formModel.value.id && flag == 0) {
    // 取消修改操作
    formModel.value = { ...emptyModel }
    isFinished.value = true
    return
  }

  try {
    // 1. 创建运动记录
    await createExerciseRecordUtil(formModel.value)
    ElMessage.success(formModel.value.id ? '修改成功' : flag == 0 ? '添加成功' : '运动数据记录完成')
    // 2. 清空表单
    formModel.value = { ...emptyModel }
    exerciseList.value = []
    formRef.value.resetFields()
    // 3. 设置完成状态
    if (flag == 1 || formModel.value.id) isFinished.value = true
  } catch (error) {
    ElMessage.error('添加失败')
    Promise.reject(error)
  }
}
// 页面是否显示
const isShow = ref(false)
// 运动数据记录是否完成
const isFinished = ref(true)
// 运动记录列表
const exerciseRecordList = ref<ExerciseRecordI[]>([])
// 实际消耗
const realConsume = ref(0)
// 获取运动记录
const getExerciseRecordList = async () => {
  try {
    exerciseRecordList.value = await getExerciseRecordByDateUtil(emptyModel.date)

    if (!exerciseRecordList.value.length) {
      isFinished.value = false
      return
    }

    isFinished.value = true
    realConsume.value = exerciseRecordList.value.reduce((sum, item) => sum + item.calories, 0)
  } catch (error) {
    ElMessage.error('获取运动记录失败')
    Promise.reject(error)
  }
}
// 监听 isFinished
watch(
  isFinished,
  async () => {
    if (isFinished.value) {
      // 获取用户运动数据
      setTimeout(async () => {
        isShow.value = false
        await getExerciseRecordList()
        isShow.value = true
      }, 100)
    }
  },
  { immediate: true },
)
// 表格中的修改按钮点击事件
const handelTableModify = async (row: ExerciseRecordI) => {
  formModel.value = { ...row }
  // 获取运动列表
  exerciseList.value = await getExerciseListByNameUtil(formModel.value.exercise_name)
  // 设置运动单位
  const exercise = exerciseList.value.find((item) => item.name == formModel.value.exercise_name)
  unit.value = exercise?.unit || ''
  // 设置完成状态
  isFinished.value = false
}
// 表格中的删除按钮点击事件
const handelTableDelete = async (row: ExerciseRecordI) => {
  try {
    await deleteExerciseRecordUtil(row)
    await getExerciseRecordList()
    ElMessage.success('删除成功')
  } catch (error) {
    ElMessage.error('删除失败')
    Promise.reject(error)
  }
}
</script>

<template>
  <div class="page-container" v-if="isShow">
    <!-- 添加运动数据 -->
    <el-form :model="formModel" label-width="120px" :rules="rules" ref="formRef" v-if="!isFinished">
      <el-form-item label="运动名称" prop="exercise_name" class="MyRadio">
        <div>
          <van-field
            v-model="formModel.exercise_name"
            is-link
            readonly
            placeholder="请选择运动"
            @click="showPopupType = 'exercise'"
          />
          <van-popup :show="showPopupType == 'exercise'" round position="center">
            <van-search
              shape="round"
              v-model="searchName"
              show-action
              placeholder="请输入运动名称"
              @search="onSearch"
              @click-left-icon="onSearch"
              @cancel="cancelOnExercisePopup"
            />
            <van-picker
              v-show="pickerNameList.length > 0"
              :columns="pickerNameList"
              @confirm="confirmExerciseName"
              cancel-button-text=""
            />
          </van-popup>
        </div>
      </el-form-item>
      <el-form-item label="运动量" prop="amount_unit" class="MyRadio">
        <div>
          <van-field
            v-model="formModel.amount_unit"
            is-link
            readonly
            placeholder="请选择运动量"
            @click="confirmExerciseAmountBefore"
          />
          <van-popup :show="showPopupType == 'exercise_amount'" round position="center">
            <van-picker
              :columns="listByUserSelect(unit)"
              @confirm="confirmExerciseAmount"
              @cancel="showPopupType = ''"
            />
          </van-popup>
        </div>
      </el-form-item>
      <el-form-item label="消耗热量" class="MyRadio">
        <div style="width: 65%">
          <van-field
            :model-value="formModel.calories + ' 千卡'"
            readonly
            placeholder="食物总热量"
          />
        </div>
      </el-form-item>
      <el-form-item label="">
        <div
          style="
            display: flex;
            justify-content: space-around;
            width: 100%;
            margin-right: 40%;
            margin-top: 20px;
          "
        >
          <el-button type="primary" @click="addExercise(0)">{{
            formModel.id ? '取消' : '添加'
          }}</el-button>
          <el-button type="success" @click="addExercise(1)">{{
            formModel.id ? '修改' : '完成'
          }}</el-button>
        </div>
      </el-form-item>
    </el-form>
    <!-- 显示饮食数据 -->
    <div v-else>
      <!-- 提示 -->
      <div class="border-header">
        <el-button type="primary" @click="isFinished = false">继续添加</el-button>
        <div class="gradient-text">
          您今天一共消耗了
          <span class="keyword">{{ realConsume }}千卡</span>
          ,比计划消耗{{ realConsume - planStore.recConsume > 0 ? '多' : '少' }}了
          <span class="keyword">{{ Math.abs(realConsume - planStore.recConsume) }}千卡</span>
          哦，大约
          <span class="keyword"
            >{{ (Math.abs(realConsume - planStore.recConsume) / 250).toFixed(1) }}个</span
          >
          馒头。以下是您今天的运动记录
        </div>
      </div>
      <!-- 表格 -->
      <el-table :data="exerciseRecordList" border>
        <el-table-column label="运动名称" prop="exercise_name" align="center"></el-table-column>
        <el-table-column label="运动量" prop="amount_unit" align="center"></el-table-column>
        <el-table-column label="消耗热量(千卡)" prop="calories" align="center"></el-table-column>
        <el-table-column label="操作" align="center">
          <template #default="{ row }">
            <el-button type="text" @click="handelTableModify(row)">修改</el-button>
            <el-popconfirm title="确定删除吗?" @confirm="handelTableDelete(row)">
              <template #reference>
                <el-button type="text">删除</el-button>
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
    </div>
  </div>
</template>

<style scoped lang="less">
.page-container {
  .el-form {
    width: 40%;
    margin: 60px 25% auto 25%;

    .MyRadio {
      ::v-deep(.el-form-item__label) {
        padding: 6px 12px 0 0;
      }
    }

    .van-popup {
      width: 30%;
      height: 60%;
      padding: 20px;
    }
  }

  .border-header {
    display: flex;
    align-items: center;
    margin-bottom: 20px;
    margin-top: -20px;

    // 字体样式
    .gradient-text {
      margin-left: 50px;
      color: black;
      font-size: 12px;
      font-family: 'Comic Sans MS', cursive, sans-serif;

      .keyword {
        color: rgb(5, 88, 229); /* 高亮颜色 */
        font-weight: bold; /* 加粗 */
        text-decoration: underline; /* 下划线 */
      }
    }
  }

  .el-table {
    box-sizing: border-box; /* 确保内边距不会增加元素的总宽度和高度 */
    height: 380px;

    ::v-deep(.el-table__header th) {
      background-color: rgb(237, 237, 237, 0.9);
      color: rgb(43, 37, 37);
      padding: 10px 0;
    }

    ::v-deep(.el-table__body tr) {
      height: 50px;
    }
  }
}
</style>
